Deploy Perforce Server into Kubernetes
Why Perforce
Perforce is a version control tool just like git, svn, but optimized for large binary files.
Perforce is widely used by top tier game studios like Naughty Dogs, Electronic Arts and Ubisoft.
To me, the reason I choose Perfoce rather than Git LFS is that I already have a k8s cluster up and running and don't want to buy datapacks on Github as there would be large, large asset files for game projects.
Dockerfile
All my nodes are arm64-based AWS virtual machines. Perforce don't maintain Linux packages for arm64 anymore. I tried the way to build docker image by downloading binaries and it worked.
FROM ubuntu:jammy
# Update our main system
RUN apt-get update -y
# Install dependencies
RUN apt-get install -y wget tar
# Set the working directory
WORKDIR /perforce
# Download and extract Perforce binaries
RUN wget https://www.perforce.com/downloads/perforce/r24.1/bin.linux26aarch64/helix-core-server.tgz -O helix-core-server.tgz \
&& tar -xzf helix-core-server.tgz \
&& rm helix-core-server.tgz
# Add Perforce binaries to PATH
ENV PATH="/perforce:${PATH}"
# Define environment variables for Perforce
ENV P4ROOT=/perforce
ENV P4PORT=1666
# Expose the Perforce server port
EXPOSE 1666
# Start Perforce server and tail logs
CMD p4d -r /perforce -p $P4PORT -L /perforce/logs/log && tail -F /perforce/logs/log
The download url can be found on official perforce download page. By the time when this article is written, the latest version for helix server is 2024.1/2596294
. Be sure to check new releases when you make your own docker image.
Build and push to registry
#!/bin/bash
# Variables
repositoryHost='your-registry'
repository='your-repo'
imageBaseName='helix-core-server'
platforms='linux/arm64' # Define platforms
# Extract version from package.json
version='0.0.1'
# Full image tag with version
imageTag="$imageBaseName:$version"
# Create a new builder instance that supports multi-platform builds, if not already done
docker buildx create --name mymultiarchbuilder --use
# Start up the build instance, if not already done
docker buildx inspect --bootstrap
# Build and push Docker image
docker buildx build --platform $platforms -t $repositoryHost/$repository/$imageTag --push .
K8s Deployment
Everytime I expose a service from my k8s cluster I will consider DDoS problem because you will meet them sooner or later if you don't. Usually I expose them through nodeport + nginx ingress controller, and put them behind cloudflare.
However Perforce is not a http service and cannot be proxied through cloudflare orange cloud. I have to disable orange cloud and access them directly using nodeport. It is not a big problem because I only use it for myself. If the Perforce server is going to be public over the Internet, you will have to consider DDoS protection.
deployment.yaml
I already have a PVC setup based on juicefs in my k8s cluster, so the pod will not lose any data during redeployments. I mapped data/perforce-root
in juicefs for /etc/perforce
and /perforce
inside container. Make sure to adjust it for your case.
This article doesn't talk about how to deploy juicefs to your k8s cluster as PersistentVolume. They are detailed written in the official documentation of juicefs.
apiVersion: apps/v1
kind: Deployment
metadata:
name: perforce-server
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: perforce-server
template:
metadata:
labels:
app: perforce-server
spec:
containers:
- name: perforce-server
image: your-registry/helix-core-server:0.0.1
ports:
- containerPort: 1666
volumeMounts:
- mountPath: /etc/perforce
name: perforce-storage
subPath: data/perforce-root/etc/perfoce
- mountPath: /perfoce
name: perforce-storage
subPath: data/perfoce-root/perfoce
env:
- name: P4ROOT
value: /perforce
- name: P4PORT
value: "1666"
volumes:
- name: perforce-storage
persistentVolumeClaim:
claimName: juicefs-pvc
nodeport.yaml
apiVersion: v1
kind: Service
metadata:
name: perforce-service
namespace: default
spec:
type: NodePort
ports:
- port: 1666
targetPort: 1666
selector:
app: perforce-server
Apply them
kubectl apply -f deployment.yaml
kubectl apply -f nodeport.yaml
Check port k8s assigned for perforce-server
by
kubectl get svc
In my case the port is 30222. Point your domain to the public IP of node. Your Perforce address is your-domain:30222
. Remember to adjust your firewall or other related security policies.
Set Password
Although you can do this step using init containers with some tricks and let k8s do this for you, it is tedious so I just get into the pod and do it manually and only once because the setup will be persistent as the pod is provided with PVC.
Get pod name
kubectl get pods -l app=perforce-server
Then get into it
kubectl exec -it pod-name-you-just-got -it -- /bin/bash
Enable authorization
p4 protect -o > protections.p4s
In googled results, the usernames of admin are super
s but in my protection.p4s
I only see a root
. Never mind, just set password for root
p4 -u root passwd
Now you can connect to Perforce server using your-domain:30222
with root
and password.
You can connect to it with root
using p4admin
GUI client and create users with normal permission for daily development.